#pragma once

#ifdef __QT5_TARGET

#include <QtCore/QDate>
#include <QtCore/QHash>
#include <QtCore/QStringList>
#include <QtSql/QSqlQuery>

#else

#include <QSqlQuery>
#include <QStringList>
#include <QDate>
#include <QHash>

#endif

#include "Patient.h"
#include "korlapadmin_model_global.h"
#include "Exception.h"
#include "Visit.h"

class KORLAPADMIN_MODEL_EXPORT PatientManager
{
public:
	PatientManager(void);
	~PatientManager(void);

	//Initialization of the manager
	int init();

	//get All patients
	QList<Patient*> getAllPatients();

	//get a list of field for all patients
	QStringList getAllPatientNames();
	QList<unsigned int> getAllIds();
	QList<QString> getAllPhones();

	//finding patient by one of its unique field.
	const Patient* findPatientByFileNumber(unsigned int filenr);
	const Patient* findPatientByPhone(const QString& phone);
	
	//We can find a Patient by its combobox index
	const Patient* findPatientByNameIndex(int index);

	// Find indeces by file #

	int getNameIndexByFileNr(unsigned int fileno);
	int getFileIndexByFileNr(unsigned int fileno);
	int getPhoneIndexByFileNr(unsigned int fileno);
	
	//Binary search algorithms to determine where to insert the new items
	int findIndexByName(const QString& name);
	int findIndexByPhone(const QString& phone);
	int findIndexByFileNo(unsigned int fileNo);

	// Modifying the list
	QList<int> addPatient(Patient* p);
	int deletePatient(Patient* p); // I'm not sure we will need this operation
	
	int queryVisits(const Patient* p); // query all visits belonging to that Patient
	QDate getLastVisitDate(const Patient* p); // return the date of the last visit
	
	QList<Visit*> getVisits();
	QList<Visit*> getAllUnfinished();
	Visit* getLastVisit();
	Visit* getVisit(unsigned int visit_id);
	QList<Visit*> getVisits(int pos, int number);
	QList<Visit*> getVisits(QDate date);
	QList<Visit*> getVisits(QDate from, QDate to);
	QList<Visit*> getVisits(const QString& filter);
	Visit* getFirstVisit();
	QList<Visit*> getFollowUps();
private:
	int queryPatients();
	void fillHashTables(Patient* p);
	QList<int> insertedIndeces;
	QHash<unsigned int,Patient*>* fileNr_Patient_mapping; //Lookup patient by its file number;
	QHash<QString,Patient*> phone_Patient_mapping; // Lookup patient by its phone number;

	// These mappings are nesessary for identifying a patient by a combobox index.

	QList<unsigned int> nameIndex_fileNr_mapping;
	

	QHash<unsigned int, int> fileNr_nameIndex_reverseLookup;
	QHash<unsigned int, int> fileNr_fileIndex_reverseLookup;
	QHash<unsigned int, int> fileNr,phoneIndex_reverseLookup;
	// These are sorted list for fast insertion and lookup.
	QStringList names;
	QStringList phones;
	QList<unsigned int> file_numbers;

	QHash<unsigned int,Visit*> visits;
	
};
